/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_httpd.htm
 *
 * Zhiqim Httpd is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.httpd.nio;

import java.nio.ByteBuffer;

import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;

import org.zhiqim.httpd.HttpInputStream;
import org.zhiqim.kernel.logging.Log;
import org.zhiqim.kernel.logging.LogFactory;

/**
 * HTTPS对缓冲的封装处理
 *
 * @version v1.0.0 @author zouzhigang 2018-11-27 新建与整理
 */
public class HttpNioSslBuffer
{
    private static final Log log = LogFactory.getLog(HttpNioSslBuffer.class);
    
    private SSLEngine sslEngine;
    private ByteBuffer appBuf;
    private ByteBuffer tmpBuf;
    
    public HttpNioSslBuffer(SSLEngine sslEngine)
    {
        this.sslEngine = sslEngine;
        
        this.appBuf = ByteBuffer.allocate(sslEngine.getSession().getApplicationBufferSize() + 10);
        this.tmpBuf = ByteBuffer.allocate(sslEngine.getSession().getPacketBufferSize());
        this.tmpBuf.flip();
    }
    
    public int parseBuffer(ByteBuffer netBuf, HttpInputStream input)
    {
        try
        {
            netBuf.flip();
            
            //默认使用网络缓冲
            ByteBuffer curBuf = netBuf;
            if (tmpBuf.hasRemaining())
            {//如果有临时缓冲，则新建缓冲把临时缓冲放置在当前缓冲的前面，并置空临时缓冲
                curBuf = ByteBuffer.allocate(tmpBuf.remaining() + netBuf.remaining());
                curBuf.put(tmpBuf).put(netBuf).flip();
                tmpBuf.clear().flip();
            }
                
            while (curBuf.hasRemaining())
            {
                appBuf.clear();
                SSLEngineResult result = sslEngine.unwrap(curBuf, appBuf);
                if (result.getStatus() == SSLEngineResult.Status.OK)
                {//正常
                    input.addBuffer(appBuf);
                    continue;
                }
                else if (result.getStatus() == SSLEngineResult.Status.BUFFER_UNDERFLOW)
                {//下溢，把当前的放置到临时缓冲中，等待后面的数据
                    tmpBuf.clear();
                    tmpBuf.put(curBuf);
                    tmpBuf.flip();
                    return 0;
                }
                else if (result.getStatus() == SSLEngineResult.Status.CLOSED)
                {//关闭
                    return -1;
                }
                else
                {//其他的暂不支持，记录日志观察
                    log.error("HTTPS解析网络包时，不支持状态[%s]", result.getStatus());
                    return -1;
                }
            }
            
            return 1;
        }
        catch (Exception e)
        {
            log.error("HTTPS解析网络包时异常", e);
            return -1;
        }
    }
}
